package com.example.demo.util.gson;

import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TypeAdaptersRedefine {
	public static final String EMPTY = "";
	
	public static final TypeAdapter<Object> MAP = new TypeAdapter<Object>() {
		
		@Override
		public Object read(JsonReader in) throws IOException {
			JsonToken token = in.peek();
			switch (token) {
				case BEGIN_ARRAY:
					List<Object> list = new ArrayList<Object>();
					in.beginArray();
					while (in.hasNext()) {
						list.add(read(in));
					}
					in.endArray();
					return list;
				case BEGIN_OBJECT:
					Map<String, Object> map = new LinkedTreeMap<String, Object>();
					in.beginObject();
					while (in.hasNext()) {
						map.put(in.nextName(), read(in));
					}
					in.endObject();
					return map;
				case STRING:
					return in.nextString();
				case NUMBER:
					/**
					 * 改写数字的处理逻辑，将数字值分为整型与浮点型。
					 */
					double dbNum = in.nextDouble();
					// 数字超过long的最大值，返回浮点类型
					if (dbNum > Long.MAX_VALUE) {
						return dbNum;
					}
					// 判断数字是否为整数值
					long lngNum = (long) dbNum;
                    return dbNum;
				case BOOLEAN:
					return in.nextBoolean();
				case NULL:
					in.nextNull();
					return null;
				default:
					throw new IllegalStateException();
			}
		}
		
		@Override
		public void write(JsonWriter out, Object value) throws IOException {
		}
		
	};
	/**
	 * 对于String 类型 的 策略
	 */
	public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
		//进行反序列化
		@Override
		public String read(JsonReader reader) {
			try {
				if (reader.peek() == JsonToken.NULL) {
					reader.nextNull();
					return EMPTY;
//					return null;
				}
				
				String result = reader.nextString();
				//要进行属性值的判断 若为 空字符串 则返回 "" 否则返回 本身的值
				return result.length() > 0 ? result : EMPTY;
				//要进行属性值的判断 若为 空字符串 则返回null 否则返回 本身的值
				//return result.length() > 0 ? result : null;
			} catch (Exception e) {
				throw new JsonSyntaxException(e);
			}
		}
		
		// 进行序列化
		@Override
		public void write(JsonWriter writer, String value) {
			try {
				if (value == null) {
					writer.value(EMPTY);
					return;
				}
				writer.value(value);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
	
	
	/**
	 * 对于int 和 Integer 类型
	 * 由于 int 类型 有默认值 0，
	 * -- 通常我们无法确定 0 是否具备实际意义
	 * 但是 Integer 的类型 null , 我们可以确定的是 -- 无意义的
	 * <p>
	 * 因此在设计属性的类型是 通常采用 Integer  而不是 int 类型
	 * <p>
	 * 故 由于 int 的 0  具备 实际意义  -- 不进行转换
	 * 而是转换 Integer 类型的 null 值
	 */
	public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
		@Override
		public Number read(JsonReader in) throws IOException {
			System.out.println(in.peek() + " ----->");
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return null;
			}
			if (in.peek() == JsonToken.STRING) {
				in.nextString();
				return null;
			}
			return in.nextInt();
		}
		
		@Override
		public void write(JsonWriter out, Number value) throws IOException {
			if (value == null) {
				out.value(EMPTY);
			} else {
				out.value(value);
			}
		}
	};
	
	/**
	 * 对于double类型的转换
	 */
	public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() {
		@Override
		public Number read(JsonReader in) throws IOException {
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return null;
			}
			if (in.peek() == JsonToken.STRING) {
				in.nextString();
				return null;
			}
			return in.nextDouble();
		}
		
		@Override
		public void write(JsonWriter out, Number value) throws IOException {
			if (value == null) {
				out.value(EMPTY);
			} else {
				out.value(value);
			}
		}
	};
	
	
}

